gdk/win32/gdkevents-win32.c Fix transient windows on Win32 so that when a
authorCody Russell <bratsche@gnome.org>
Thu, 12 Jul 2007 23:38:30 +0000 (23:38 +0000)
committerCody Russell <bratsche@src.gnome.org>
Thu, 12 Jul 2007 23:38:30 +0000 (23:38 +0000)
2007-07-12  Cody Russell  <bratsche@gnome.org>

* gdk/win32/gdkevents-win32.c
* gdk/win32/gdkwindow-win32.[ch]: Fix transient windows on Win32
so that when a transient child window is closed (particularly when
there are 3 or more levels of transient windows), the correct window
receives focus rather than a seemingly random window. (#112404)

svn path=/trunk/; revision=18461

ChangeLog
gdk/win32/gdkevents-win32.c
gdk/win32/gdkwindow-win32.c
gdk/win32/gdkwindow-win32.h

index 5e940503253ed5e8ce34128155588323deed0e19..0293d90b08d7ab78b7f9acd48894b0441b6cb58e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2007-07-12  Cody Russell  <bratsche@gnome.org>
+
+       * gdk/win32/gdkevents-win32.c
+       * gdk/win32/gdkwindow-win32.[ch]: Fix transient windows on Win32
+       so that when a transient child window is closed (particularly when
+       there are 3 or more levels of transient windows), the correct window
+       receives focus rather than a seemingly random window. (#112404)
+
 2007-07-12  Attilio Fiandrotti  <attilio.fiandrotti@gmail.com>
 
        * gdk/directfb/gdkevents-directfb.c:
index 5059a88993c3d63c097b43f0a5e1040f84d2e6bc..111551393219d21122c6d6b9df6aef2ce5688d05 100644 (file)
@@ -1,6 +1,7 @@
 /* GDK - The GIMP Drawing Kit
  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
  * Copyright (C) 1998-2002 Tor Lillqvist
+ * Copyright (C) 2007 Cody Russell
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -2816,7 +2817,17 @@ gdk_event_translate (MSG  *msg,
       event->any.window = window;
 
       append_event (event);
-      
+
+      if (event->any.type == GDK_UNMAP)
+       {
+         impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
+
+         if (impl->transient_owner && GetForegroundWindow () == GDK_WINDOW_HWND (window))
+           {
+             SetForegroundWindow (GDK_WINDOW_HWND (impl->transient_owner));
+           }
+       }
+
       if (event->any.type == GDK_UNMAP &&
          p_grab_window == window)
        gdk_pointer_ungrab (msg->time);
@@ -3213,6 +3224,13 @@ gdk_event_translate (MSG  *msg,
 
       append_event (event);
 
+      impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
+
+      if (impl->transient_owner && GetForegroundWindow() == GDK_WINDOW_HWND (window))
+       {
+         SetForegroundWindow (GDK_WINDOW_HWND (impl->transient_owner));
+       }
+
       return_val = TRUE;
       break;
 
index b3baab5afe46bbce2cc9dd3b75d303d49bcdadf9..d0e2ee6cba25025e240195941cc9078b96e8447b 100644 (file)
@@ -2,6 +2,7 @@
  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
  * Copyright (C) 1998-2004 Tor Lillqvist
  * Copyright (C) 2001-2004 Hans Breuer
+ * Copyright (C) 2007 Cody Russell
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -105,6 +106,7 @@ gdk_window_impl_win32_init (GdkWindowImplWin32 *impl)
   impl->hint_flags = 0;
   impl->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
   impl->extension_events_selected = FALSE;
+  impl->transient_owner = NULL;
 }
 
 static void
@@ -828,6 +830,7 @@ _gdk_windowing_window_destroy (GdkWindow *window,
                               gboolean   foreign_destroy)
 {
   GdkWindowObject *private = (GdkWindowObject *)window;
+  GdkWindowImplWin32 *window_impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
 
   g_return_if_fail (GDK_IS_WINDOW (window));
   
@@ -837,6 +840,11 @@ _gdk_windowing_window_destroy (GdkWindow *window,
   if (private->extension_events != 0)
     _gdk_input_window_destroy (window);
 
+  /* Remove ourself from our transient owner */
+  if (window_impl->transient_owner != NULL)
+    {
+      gdk_window_set_transient_for (window, NULL);
+    }
 
   if (!recursing && !foreign_destroy)
     {
@@ -845,6 +853,7 @@ _gdk_windowing_window_destroy (GdkWindow *window,
       private->destroyed = TRUE;
       DestroyWindow (GDK_WINDOW_HWND (window));
     }
+
   gdk_win32_handle_table_remove (GDK_WINDOW_HWND (window));
 }
 
@@ -1181,7 +1190,9 @@ gdk_window_move (GdkWindow *window,
    * windows! Especially in the case of gtkplug/socket.
    */ 
   if (GetAncestor (GDK_WINDOW_HWND (window), GA_PARENT) != GetDesktopWindow ())
-    _gdk_window_move_resize_child (window, x, y, impl->width, impl->height);
+    {
+      _gdk_window_move_resize_child (window, x, y, impl->width, impl->height);
+    }
   else
     {
       RECT outer_rect;
@@ -1228,7 +1239,9 @@ gdk_window_resize (GdkWindow *window,
     return;
 
   if (GetAncestor (GDK_WINDOW_HWND (window), GA_PARENT) != GetDesktopWindow ())
-    _gdk_window_move_resize_child (window, private->x, private->y, width, height);
+    {
+      _gdk_window_move_resize_child (window, private->x, private->y, width, height);
+    }
   else
     {
       RECT outer_rect;
@@ -1280,7 +1293,9 @@ gdk_window_move_resize (GdkWindow *window,
                           width, height, x, y));
   
   if (GetAncestor (GDK_WINDOW_HWND (window), GA_PARENT) != GetDesktopWindow ())
-    _gdk_window_move_resize_child (window, x, y, width, height);
+    {
+      _gdk_window_move_resize_child (window, x, y, width, height);
+    }
   else
     {
       RECT outer_rect;
@@ -1908,29 +1923,35 @@ gdk_window_set_role (GdkWindow   *window,
   /* XXX */
 }
 
-void          
+void
 gdk_window_set_transient_for (GdkWindow *window, 
                              GdkWindow *parent)
 {
   HWND window_id, parent_id;
+  GdkWindowImplWin32 *window_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
 
   g_return_if_fail (GDK_IS_WINDOW (window));
-  
-  GDK_NOTE (MISC, g_print ("gdk_window_set_transient_for: %p: %p\n",
-                          GDK_WINDOW_HWND (window),
-                          GDK_WINDOW_HWND (parent)));
 
-  if (GDK_WINDOW_DESTROYED (window) || GDK_WINDOW_DESTROYED (parent))
-    return;
+  window_id = GDK_WINDOW_HWND (window);
+  parent_id = parent != NULL ? GDK_WINDOW_HWND (parent) : NULL;
+
+  if (GDK_WINDOW_DESTROYED (window) || (parent && GDK_WINDOW_DESTROYED (parent)))
+    {
+      if (GDK_WINDOW_DESTROYED (window))
+       GDK_NOTE (MISC, g_print ("... destroyed!\n"));
+      else
+       GDK_NOTE (MISC, g_print ("... owner destroyed!\n"));
+
+      return;
+    }
 
   if (((GdkWindowObject *) window)->window_type == GDK_WINDOW_CHILD)
     {
       GDK_NOTE (MISC, g_print ("... a child window!\n"));
       return;
     }
-  
-  window_id = GDK_WINDOW_HWND (window);
-  parent_id = GDK_WINDOW_HWND (parent);
+
+  window_impl->transient_owner = parent;
 
   /* This changes the *owner* of the window, despite the misleading
    * name. (Owner and parent are unrelated concepts.) At least that's
@@ -3386,11 +3407,14 @@ gdk_window_set_modal_hint (GdkWindow *window,
 
   private->modal_hint = modal;
 
+#if 0
+  /* Not sure about this one.. -- Cody */
   if (GDK_WINDOW_IS_MAPPED (window))
     API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), 
                             modal ? HWND_TOPMOST : HWND_NOTOPMOST,
                             0, 0, 0, 0,
                             SWP_NOMOVE | SWP_NOSIZE));
+#endif
 }
 
 void
index 892110b5a104d0c330bc62e1ea4c4d8ef23a1184..8a697565a45f0ad6536c6cd221aebfb78f206f70 100644 (file)
@@ -86,6 +86,8 @@ struct _GdkWindowImplWin32
   GdkWindowTypeHint type_hint;
 
   gboolean extension_events_selected;
+
+  GdkWindow *transient_owner;
 };
  
 struct _GdkWindowImplWin32Class